#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Collections.ObjectModel;
using System.Runtime.Remoting;
using Microsoft.Xna.Framework;

#endregion

namespace SkyBurner
{
    public enum XMLPropertyBagValueType
    {
        vtString,
        vtInteger,
        vtFloat,
        vtVector2,
        vtVector3,
        vtVector4
    }

    public class XMLPropertyBag
    {
        #region ItemVariant class
        protected class ItemVariant
        {
            int m_nInteger;
            float m_fFloat;
            String m_sString;
            Vector2 m_vVector2 = new Vector2();
            Vector3 m_vVector3 = new Vector3();
            Vector4 m_vVector4 = new Vector4();

            public Object GetValue(XMLPropertyBagValueType pValueType)
            {
                switch (pValueType)
                {
                    case XMLPropertyBagValueType.vtString:
                        return m_sString;

                    case XMLPropertyBagValueType.vtInteger:
                        return m_nInteger;

                    case XMLPropertyBagValueType.vtFloat:
                        return m_fFloat;

                    case XMLPropertyBagValueType.vtVector2:
                        return m_vVector2;

                    case XMLPropertyBagValueType.vtVector3:
                        return m_vVector3;

                    case XMLPropertyBagValueType.vtVector4:
                        return m_vVector4;
                }

                return null;
            }

            public ItemVariant(String pName, String pValue)
            {
                String[] split;

                m_sString = pValue;

                try
                {
                    m_nInteger = Convert.ToInt32(m_sString);
                }
                catch 
                {
                    m_nInteger = 0;
                }

                try
                {
                    m_fFloat = Convert.ToSingle(m_sString);
                }
                catch
                {
                    m_fFloat = 0.0f;
                }

                split = m_sString.Split(' ');
                if (split.Length == 2)
                {
                    m_vVector2.X = Convert.ToSingle(split[0]);
                    m_vVector2.Y = Convert.ToSingle(split[1]);
                }

                split = m_sString.Split(' ');
                if (split.Length == 3)
                {
                    m_vVector3.X = Convert.ToSingle(split[0]);
                    m_vVector3.Y = Convert.ToSingle(split[1]);
                    m_vVector3.Z = Convert.ToSingle(split[2]);
                }

                split = m_sString.Split(' ');
                if (split.Length == 4)
                {
                    m_vVector4.X = Convert.ToSingle(split[0]);
                    m_vVector4.Y = Convert.ToSingle(split[1]);
                    m_vVector4.Z = Convert.ToSingle(split[2]);
                    m_vVector4.W = Convert.ToSingle(split[3]);
                }
            }
        }
        #endregion

        protected List<Pair<String, ItemVariant>> m_propertyBag = new List<Pair<String, ItemVariant>>();

        public XMLPropertyBag(XmlNode pXMLNode)
        {
            // build property list from XML node...
            foreach (XmlNode childNode in pXMLNode.ChildNodes)
                m_propertyBag.Add(new Pair<String, ItemVariant>(childNode.Name, new ItemVariant(childNode.Name, childNode.InnerText)));
        }

        protected ItemVariant GetItem(String pKey)
        {
            foreach(Pair<String,ItemVariant> bagElement in m_propertyBag)
            {
                if (bagElement.First == pKey)
                    return bagElement.Second;
            }
            throw new Exception(String.Format("XMLPropertyBag cannot find item with key {0}", pKey));
        }

        public T GetValue<T>(String pKey, XMLPropertyBagValueType pValueType)
        {
            return (T)GetItem(pKey).GetValue(pValueType);
        }
    }
}
